//
//  AliPayManager.m
//  SonDelivery
//
//  Created by 巩少鹏 on 2020/4/3.
//  Copyright © 2020 巩少鹏. All rights reserved.
//

#import "AliPayManager.h"
#import "APRSASigner.h"
#import "GSCurrentVC.h"

@interface AliPayManager ()
{
    NSString *pid;
    NSString *appID ;
    NSString *rsa2PrivateKey;
    NSString *rsaPrivateKey;
    NSString *appScheme ;
}
@end
@implementation AliPayManager
//非标准单例
static AliPayManager *manager = nil;
+ (AliPayManager *)defaultManager {
    @synchronized(self) {//同步 执行 防止多线程操作
        if (manager == nil) {
            manager = [[self alloc] init];
        }
    }
    return manager;
}
//配置
-(id)init{
    if (self = [super init]) {
        // 重要说明
        // 这里只是为了方便直接向商户展示支付宝的整个支付流程；所以Demo中加签过程直接放在客户端完成；
        // 真实App里，privateKey等数据严禁放在客户端，加签过程务必要放在服务端完成；
        // 防止商户私密数据泄露，造成不必要的资金损失，及面临各种安全风险；
        // 如下私钥，rsa2PrivateKey 或者 rsaPrivateKey 只需要填入一个
        // 如果商户两个都设置了，优先使用 rsa2PrivateKey
        // rsa2PrivateKey 可以保证商户交易在更加安全的环境下进行，建议使用 rsa2PrivateKey
        // 获取 rsa2PrivateKey，建议使用支付宝提供的公私钥生成工具生成，
        // 工具地址：https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=106097&docType=1
        /*============================================================================*/
        /*=======================需要填写商户app申请的===================================*/
        /*============================================================================*/
        
        [self AlipayConfig];

    }
    return self;
}

#pragma mark - 默认配置

-(void)AlipayConfig{
     pid = @"";
     appID = @"";
     rsa2PrivateKey = @"";
     rsaPrivateKey = @"";
     appScheme = @"";//!< 应用注册scheme,在AliSDKDemo-Info.plist定义URL types
}

#pragma mark   ==============点击订单支付行为==============
-(void)payOrder:(GSBizContent *)model complete:(void (^)(NSDictionary *resultDic))complete{
      if ([appID length] == 0 ||
             ([rsa2PrivateKey length] == 0 && [rsaPrivateKey length] == 0))
         {
             [self newTipsWithTitle:@"提示" message:@"缺少appId或者私钥,请检查参数设置" actionText:@"知道了"];
             return;
         }
       /*
        *生成订单信息及签名
        */
       //将商品信息赋予AlixPayOrder的成员变量
       GSOrderInfo* order = [GSOrderInfo new];
       // NOTE: app_id设置
       order.app_id = appID;
       // NOTE: 支付接口名称
       order.method = @"alipay.trade.app.pay";
       // NOTE: 参数编码格式
       order.charset = @"utf-8";
       // NOTE: 当前时间点
       NSDateFormatter* formatter = [NSDateFormatter new];
       [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
       order.timestamp = [formatter stringFromDate:[NSDate date]];
       // NOTE: 支付版本
       order.version = @"1.0";
       // NOTE: sign_type 根据商户设置的私钥来决定
       order.sign_type = (rsa2PrivateKey.length > 1)?@"RSA2":@"RSA";
    
       // NOTE: 商品数据
       order.biz_content = [GSBizContent new];
       order.biz_content.body = model.body;
       order.biz_content.subject = model.subject;
       order.biz_content.out_trade_no = model.out_trade_no; //订单ID（由商家自行制定）
       order.biz_content.timeout_express = model.timeout_express?:@"30m"; //超时时间设置
       order.biz_content.total_amount = model.total_amount; //商品价格
       
       //将商品信息拼接成字符串
       NSString *orderInfo = [order orderInfoEncoded:NO];
       NSString *orderInfoEncoded = [order orderInfoEncoded:YES];
       NSLog(@"orderSpec = %@",orderInfo);
       
       // NOTE: 获取私钥并将商户信息签名，外部商户的加签过程请务必放在服务端，防止公私钥数据泄露；
       //       需要遵循RSA签名规范，并将签名字符串base64编码和UrlEncode
       NSString *signedString = nil;
       APRSASigner* signer = [[APRSASigner alloc] initWithPrivateKey:((rsa2PrivateKey.length > 1)?rsa2PrivateKey:rsaPrivateKey)];
       if ((rsa2PrivateKey.length > 1)) {
           signedString = [signer signString:orderInfo withRSA2:YES];
       } else {
           signedString = [signer signString:orderInfo withRSA2:NO];
       }
       
       // NOTE: 如果加签成功，则继续执行支付
       if (signedString != nil) {
           // NOTE: 将签名成功字符串格式化为订单字符串,请严格按照该格式
           NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@",
                                    orderInfoEncoded, signedString];
           
           [self payOrderWithOrderString:orderString complete:complete];
       }
    
}
#pragma mark - 唤起支付
-(void)payOrderWithOrderString:(NSString *)orderString complete:(void (^)(NSDictionary *resultDic))complete{
    // NOTE: 调用支付结果开始支付
     [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
         NSLog(@"reslut = %@",resultDic);
         complete(resultDic);
     }];
}



#pragma mark   ==============点击授权行为==============
-(void)new_doAPAuth:(void (^)(NSString *authCode))codeback{
    [self new_doAPAuthComplete:^(NSDictionary * _Nonnull resultDic) {
        
    } codeback:codeback];
}
-(void)new_doAPAuthComplete:(void (^)(NSDictionary *resultDic))complete codeback:(void (^)(NSString *authCode))codeback{
    //pid和appID获取失败,提示
    if ([pid length] == 0 ||
        [appID length] == 0 ||
        ([rsa2PrivateKey length] == 0 && [rsaPrivateKey length] == 0))
    {
        [self newTipsWithTitle:@"提示" message:@"缺少pid或者appID或者私钥,请检查参数设置" actionText:@"知道了"];
        return;
    }
    //生成 auth info 对象
       GSAuthInfo *authInfo = [GSAuthInfo new];
       authInfo.pid = pid;
       authInfo.appID = appID;
       
       //auth type
       NSString *authType = [[NSUserDefaults standardUserDefaults] objectForKey:@"authType"];
       if (authType) {
           authInfo.authType = authType;
       }
       
       //应用注册scheme,在AlixPayDemo-Info.plist定义URL types
//       NSString *appScheme = appScheme;
       
       // 将授权信息拼接成字符串
       NSString *authInfoStr = [authInfo description];
       NSLog(@"authInfoStr = %@",authInfoStr);
       
       // 获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
       NSString *signedString = nil;
       APRSASigner* signer = [[APRSASigner alloc] initWithPrivateKey:((rsa2PrivateKey.length > 1)?rsa2PrivateKey:rsaPrivateKey)];
       if ((rsa2PrivateKey.length > 1)) {
           signedString = [signer signString:authInfoStr withRSA2:YES];
       } else {
           signedString = [signer signString:authInfoStr withRSA2:NO];
       }
       
       // 将签名成功字符串格式化为订单字符串,请严格按照该格式
       if (signedString.length > 0) {
           authInfoStr = [NSString stringWithFormat:@"%@&sign=%@&sign_type=%@", authInfoStr, signedString, ((rsa2PrivateKey.length > 1)?@"RSA2":@"RSA")];
           [[AlipaySDK defaultService] auth_V2WithInfo:authInfoStr
                                            fromScheme:appScheme
                                              callback:^(NSDictionary *resultDic) {
                                                  NSLog(@"result = %@",resultDic);
                                                  // 解析 auth code
                                                  NSString *result = resultDic[@"result"];
                                                  NSString *authCode = nil;
                                                  if (result.length>0) {
                                                      NSArray *resultArr = [result componentsSeparatedByString:@"&"];
                                                      for (NSString *subResult in resultArr) {
                                                          if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                                                              authCode = [subResult substringFromIndex:10];
                                                              break;
                                                          }
                                                      }
                                                  }
                                                  NSLog(@"授权结果 authCode = %@", authCode?:@"");
                                                    complete(resultDic);
                                                    codeback(authCode);
                                              }];
       }
    
}




#pragma mark - 支付跳转支付宝钱包进行支付，处理支付结果
-(void)new_processOrderWithPaymentResult:(NSURL *)url{
    [self new_processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
         NSLog(@"result = %@",resultDic);
    }];
}
-(void)new_processOrderWithPaymentResult:(NSURL *)url standbyCallback:(void (^)(NSDictionary *resultDic))standbyCallback
{
    [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
        standbyCallback(resultDic);
      }];
}
#pragma mark - 授权跳转支付宝钱包进行支付，处理支付结果

-(void)new_processAuth_V2Result:(NSURL *)url {
    [self new_processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
        NSLog(@"result = %@",resultDic);
    }];
}
-(void)new_processAuth_V2Result:(NSURL *)url standbyCallback:(void (^)(NSDictionary *resultDic))standbyCallback
{
      [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
          
          // 解析 auth code
          NSString *result = resultDic[@"result"];
          NSString *authCode = nil;
          if (result.length>0) {
              NSArray *resultArr = [result componentsSeparatedByString:@"&"];
              for (NSString *subResult in resultArr) {
                  if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                      authCode = [subResult substringFromIndex:10];
                      break;
                  }
              }
          }
          NSLog(@"授权结果 authCode = %@", authCode?:@"");
          standbyCallback(resultDic);
      }];
}
#pragma mark - tips 提醒
-(void)newTipsWithTitle:(NSString *)title message:(NSString *)message actionText:(NSString *)actionText{
       UIAlertController *alert = [UIAlertController alertControllerWithTitle:title
                                                                      message:message
                                                               preferredStyle:UIAlertControllerStyleAlert];
       UIAlertAction *action = [UIAlertAction actionWithTitle:actionText
                                                        style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction *action){
                                                          
                                                      }];
       [alert addAction:action];
       [[GSCurrentVC getCurrentVC] presentViewController:alert animated:YES completion:^{ }];
       
}





@end
